
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package estsapp.expertos;

import estsapp.entidades.CodificacionBrisch;
import estsapp.entidades.Material;
import estsapp.entidades.TipoMaterial;
import estsapp.expertos.excepciones.ABMTipoMaterialException;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import persistencia.Conexion;
import persistencia.Fachada;
import persistencia.exceptions.ExcepcionFachada;

/**
 *
 * @author diego
 */
public class ExpertoABMTipoMaterial implements Experto {

    public void guardar(TipoMaterial tipo) throws ABMTipoMaterialException, ExcepcionFachada {

        validar(tipo);
        validarExistencia(tipo);
        generarCódigoTipoMaterial(tipo);
        tipo.setVigente(true);
        if (tipo.getId() == null) {
            tipo.setUltimoMaterialIngresado(0);
        }

        try {
            Conexion.getInstancia().iniciarTX();
            Fachada.getInstancia().guardar(tipo);
            Conexion.getInstancia().confirmarTx();
        } catch (ExcepcionFachada ex) {
            Conexion.getInstancia().deshacerTx();
            throw ex;
        }

    }

    public void darDeBaja(TipoMaterial tipo) throws ABMTipoMaterialException, ExcepcionFachada {
        Criteria criterioTipo = Fachada.getInstancia().crearCriterio(Material.class).add(Restrictions.eq("tipo", tipo));
        criterioTipo.add(Restrictions.eq("vigente", true));
        if (!Fachada.getInstancia().buscar(Material.class, criterioTipo).isEmpty()) {
            throw new ABMTipoMaterialException("Hay materiales vigentes del tipo: " + tipo.getNombre() + ", no se puede dar de baja.");
        }
        tipo.setVigente(false);
        try {
            Conexion.getInstancia().iniciarTX();
            Fachada.getInstancia().guardar(tipo);
            Conexion.getInstancia().confirmarTx();
        } catch (ExcepcionFachada ex) {
            Conexion.getInstancia().deshacerTx();
            throw ex;
        }
    }

    public List buscarCategoriasBrischTipoMat() {
        Criteria materiaPrima = Fachada.getInstancia().crearCriterio(CodificacionBrisch.class);
        materiaPrima.add(Restrictions.or(Restrictions.eq("nombre", "Materia Prima"), Restrictions.eq("nombre", "Producto Componente")));

        return Fachada.getInstancia().buscar(CodificacionBrisch.class, materiaPrima);
    }

    private void validarExistencia(TipoMaterial tipo) throws ABMTipoMaterialException {
        Criteria nombreTipo = Fachada.getInstancia().crearCriterio(TipoMaterial.class).add(Restrictions.eq("nombre", tipo.getNombre()).ignoreCase());
        nombreTipo.add(Restrictions.eq("tipo", tipo.getCodificacionBrisch()));
        nombreTipo.add(Restrictions.eq("vigente", true));
        List tiposEncontrados = Fachada.getInstancia().buscar(TipoMaterial.class, nombreTipo);
        if (!tiposEncontrados.isEmpty()) {
            throw new ABMTipoMaterialException("El tipo que desea ingresar ya existe.");
        }
    }

    private void validar(TipoMaterial tipo) throws ABMTipoMaterialException {
        if (tipo.getNombre().length() == 0) {
            throw new ABMTipoMaterialException("Debe ingresar Tipo de Material.");
        }
        if (tipo.getCodificacionBrisch() == null) {
            throw new ABMTipoMaterialException("Debe seleccionar categoría.");
        }
    }

    private void generarCódigoTipoMaterial(TipoMaterial tipo) {
        ExpertoCodigoBrisch generadorCodigo = (ExpertoCodigoBrisch) FabricaExpertos.getInstancia().getExperto(FabricaExpertos.expertos.GENERAR_CODIGO);
        tipo.setCodigo(generadorCodigo.generarCodigo(tipo));

    }

    /**
     * Busca todos los tipos de materiales
     *
     * @return
     */
    public List buscarTiposMateriales() {
        Criteria vigente = Fachada.getInstancia().crearCriterio(TipoMaterial.class).add(Restrictions.eq("vigente", true));
        return Fachada.getInstancia().buscar(TipoMaterial.class, vigente);
    }
}
